package com.itlong.cloud.controller.sdkV3.face;

import com.alibaba.fastjson.JSON;
import com.itlong.cloud.POJO.DTO.app.MiniSetVisitPassFaceDTO;
import com.itlong.cloud.POJO.DTO.common.PadFaceSyncDataDTO;
import com.itlong.cloud.POJO.DTO.operate.OperateDeveloperAuthDeviceAuthListDTO;
import com.itlong.cloud.POJO.DTO.operate.OperateDeviceManageGetPageDTO;
import com.itlong.cloud.POJO.DTO.property.*;
import com.itlong.cloud.POJO.DTO.sdk.CloudDeviceSDKDTO;
import com.itlong.cloud.POJO.DTO.sdk.CloudFaceApiDTO;
import com.itlong.cloud.POJO.PO.AppUserProjectPO;
import com.itlong.cloud.POJO.PO.AppUserRoomPO;
import com.itlong.cloud.POJO.PO.AppVisitorPassCodeRecordPO;
import com.itlong.cloud.POJO.PO.ProjectPO;
import com.itlong.cloud.POJO.VO.SDKMessageVO;
import com.itlong.cloud.POJO.VO.app.AppCreateBaiduFaceVO;
import com.itlong.cloud.POJO.VO.operate.OperateDeveloperAuthDeviceAuthVO;
import com.itlong.cloud.POJO.VO.operate.OperateDeviceManageInfoAllVO;
import com.itlong.cloud.POJO.VO.operate.OperateDeviceManageInfoVO;
import com.itlong.cloud.POJO.VO.operate.OperateFaceApplyInfoVO;
import com.itlong.cloud.POJO.VO.property.DeviceMediaInfoVO;
import com.itlong.cloud.POJO.VO.sdk.*;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.abstracts.BaseController;
import com.itlong.cloud.annotation.LoggerInfo;
import com.itlong.cloud.annotation.UnAuthAccessRequired;
import com.itlong.cloud.constants.LogDescConstant;
import com.itlong.cloud.enumerate.*;
import com.itlong.cloud.enumerate.ecode.AppErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.BaseErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.PropertyErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.SDKErrorCodeEnum;
import com.itlong.cloud.equip.app.IAppVisitorPassCodeRecordServiceClient;
import com.itlong.cloud.equip.operate.IOperateDeviceManageServiceClient;
import com.itlong.cloud.equip.property.IDeviceMediaInfoServiceClient;
import com.itlong.cloud.equip.property.IPadFaceSyncDataServiceClient;
import com.itlong.cloud.equip.property.IPropertyEquipServiceClient;
import com.itlong.cloud.iottp.IIotBaiduFaceServiceClient;
import com.itlong.cloud.iottp.IIotVisitorFaceServiceClient;
import com.itlong.cloud.project.operate.IOperateFaceApplyServiceClient;
import com.itlong.cloud.project.operate.IOperateProjectServiceClient;
import com.itlong.cloud.project.sdk.ISDKServerProjectServiceClient;
import com.itlong.cloud.thrown.DataAccessException;
import com.itlong.cloud.user.app.IAppMineServiceClient;
import com.itlong.cloud.user.operate.IOperateDeveloperAuthServiceClient;
import com.itlong.cloud.user.property.IPropertyHouseHoldInfoServiceClient;
import com.itlong.cloud.user.property.IPropertyVisitorServiceClient;
import com.itlong.cloud.user.sdk.IFaceSDKVisitorServiceClient;
import com.itlong.cloud.utils.data.handler.SqlUtil;
import com.itlong.cloud.utils.encrypt.Md5EncryptUtil;
import com.itlong.cloud.utils.file.ImgageUtil;
import com.itlong.cloud.utils.file.UploadFileUtil;
import com.itlong.cloud.utils.network.http.HttpProtocolUtil;
import com.itlong.cloud.utils.page.Page;
import com.itlong.cloud.utils.random.LogicIdUtil;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import sun.misc.BASE64Decoder;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;

/**
 * <desc>
 * 人脸识别API控制器
 * </desc>
 *
 * @createDate 2019/11/04
 */
@RestController
@RequestMapping("/sdkv3/cloud/face")
@RefreshScope
public class SDKFaceRecognitionController extends BaseController {

    private static Logger LOG = LoggerFactory.getLogger(SDKFaceRecognitionController.class);

    @Value("${" + PlatformConstants.FILE_FTP_HOST + "}")
    public String FILE_FTP_HOST;
    @Value("${" + PlatformConstants.FILE_FTP_PORT + "}")
    public String FILE_FTP_PORT;
    @Value("${" + PlatformConstants.FILE_FTP_USERNAME + "}")
    public String FILE_FTP_USERNAME;
    @Value("${" + PlatformConstants.FILE_FTP_PASSWORD + "}")
    public String FILE_FTP_PASSWORD;
    @Value("${" + PlatformConstants.FILE_ACCESS_URL + "}")
    public String FILE_ACCESS_URL;

    @Autowired
    IOperateFaceApplyServiceClient iOperateFaceApplyServiceClient;

    @Autowired
    IPropertyHouseHoldInfoServiceClient iPropertyHouseHoldInfoServiceClient;

    @Autowired
    IOperateProjectServiceClient iOperateProjectServiceClient;

    @Autowired
    IIotBaiduFaceServiceClient iIotBaiduFaceServiceClient;

    @Autowired
    IPadFaceSyncDataServiceClient iPadFaceSyncDataServiceClient;

    @Autowired
    IOperateDeveloperAuthServiceClient iOperateDeveloperAuthServiceClient;

    @Autowired
    IIotVisitorFaceServiceClient iIotVisitorFaceServiceClient;

    @Autowired
    IPropertyEquipServiceClient iPropertyEquipServiceClient;

    @Autowired
    IPropertyVisitorServiceClient iPropertyVisitorServiceClient;

    @Autowired
    IAppVisitorPassCodeRecordServiceClient iAppVisitorPassCodeRecordServiceClient;

    @Autowired
    IFaceSDKVisitorServiceClient iFaceSDKVisitorServiceClient;

    @Autowired
    ISDKServerProjectServiceClient isdkServerProjectServiceClient;

    @Autowired
    IDeviceMediaInfoServiceClient iDeviceMediaInfoServiceClient;

    @Autowired
    IAppMineServiceClient iAppMineServiceClient;

    @Autowired
    IOperateDeviceManageServiceClient iOperateDeviceManageServiceClient;

    /**
     * <desc>
     * 添加用户并绑定房间的关系
     * <desc/>
     *
     * @return Object   标准格式化响应结果
     * @author Qiang.S
     * @createDate 2019/11/04
     */
    @ResponseBody
    @RequestMapping("/addUserBindRoom")
    @LoggerInfo(operateDesc = LogDescConstant.SDK_FACE_ADD_USER_BIND_ROOM_LOG_DESC)
    public Object addUserBindRoom() {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        try {
            CloudFaceApiDTO dto = HttpProtocolUtil.parseRequestParamToDTO(CloudFaceApiDTO.class, request);
            //保存生成操作日志所需信息 详细描述和接口类别
            //解决上传参数中有图片使操作日志写不了库
            Map map1 = SqlUtil.convertBeanToMapParams(dto);
            map1.put("imageStr","");
            request.setAttribute("remark",map1.toString());
            request.setAttribute("portType", LogDescConstant.SDK_CLOUD_DEVICE_TYPE_LOG_DESC);
            String responseTimestamp = new Date().getTime() + "";
            dto.setResponseTimestamp(responseTimestamp);
            if (StringUtils.isEmpty(dto.getProjectId()) || StringUtils.isEmpty(dto.getPhoneNum()) || StringUtils.isEmpty(dto.getRealName())
                    || (dto.getGender() != 1 && dto.getGender() != 0) || StringUtils.isEmpty(dto.getBuildId()) || StringUtils.isEmpty(dto.getUnitId())
                    || StringUtils.isEmpty(dto.getRoomId()) || StringUtils.isEmpty(dto.getRoomNum())
                    || (dto.getHouserType() != 1 && dto.getHouserType() != 2 && dto.getHouserType() != 3)) {
                return new SDKMessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode(), dto.getRequestId(), responseTimestamp, "");
            }
            //权限判断
            OperateDeveloperAuthDeviceAuthListDTO operateDeveloperAuthDeviceAuthListDTO = new OperateDeveloperAuthDeviceAuthListDTO();
            operateDeveloperAuthDeviceAuthListDTO.setUserId(request.getAttribute("appId").toString());
            operateDeveloperAuthDeviceAuthListDTO.setProjectId(dto.getProjectId());
            OperateDeveloperAuthDeviceAuthVO operateDeveloperAuthDeviceAuthVO = iOperateDeveloperAuthServiceClient.deviceAuthList(operateDeveloperAuthDeviceAuthListDTO);
            if (StringUtils.isNotEmpty(dto.getImageStr()) && (operateDeveloperAuthDeviceAuthVO == null || operateDeveloperAuthDeviceAuthVO.getFaceRecognitionApi() != 1)) {//没有权限
                return new SDKMessageVO(SDKErrorCodeEnum.SDK_FACE_API_AUTHORITY_ERR.getErrorCode(), dto.getRequestId(), responseTimestamp, "");
            }
            String regex = "^1[3|4|5|6|7|8|9]\\d{9}$";
            if (dto.getPhoneNum().length() != 11 || !Pattern.compile(regex).matcher(dto.getPhoneNum()).matches()) {
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_PHONENUM_ERR.getErrorCode(), dto.getRequestId(), responseTimestamp, "");
            }
            //查询手机号是否存在
            Integer result = iPropertyHouseHoldInfoServiceClient.getAppUserExistStatus(dto.getProjectId(), dto.getPhoneNum());
            if (result > 0) {
                return new SDKMessageVO(AppErrorCodeEnum.EXIST_PHONENO.getErrorCode(), dto.getRequestId(), responseTimestamp, "");
            }
            //查询当前项目信息
            ProjectPO projectPO = iOperateProjectServiceClient.getOneProject(dto.getProjectId());
            List<AppUserRoomDTO> appUserRoomDTOS = new ArrayList<>();
            AppUserRoomDTO appUserRoomDTO1 = new AppUserRoomDTO();
            appUserRoomDTO1.setBuildId(dto.getBuildId());
            appUserRoomDTO1.setUnitId(dto.getUnitId());
            appUserRoomDTO1.setRoomId(dto.getRoomId());
            appUserRoomDTO1.setRoomNum(dto.getRoomNum());
            appUserRoomDTO1.setHouserType(dto.getHouserType());
            appUserRoomDTOS.add(appUserRoomDTO1);

            //住宅最大授权数，最大为10
            Integer authMaxNum = projectPO.getAuthMaxNum();
            //办公最大授权数，最大为500
            Integer officeAuthMaxNum = projectPO.getOfficeAuthMaxNum();
            if (officeAuthMaxNum == 0) {
                officeAuthMaxNum = 11;
            }
            //用户房间信息不能为空
            if ((appUserRoomDTOS == null) || (appUserRoomDTOS.size() == 0)) {
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_USERROOM_NOT_NULL.getErrorCode(), dto.getRequestId(), responseTimestamp, "");
            }
            //判断新加住户业主房间地址中是否已存在业主
            //Map<String, value> ：isExist业主是否存在，roomNum 业主存在时的房间号,userId 业主userId
            Map<String, String> resultMap = this.checkOwnerExist(appUserRoomDTOS);
            String isExist = resultMap.get("isExist");
            if (StringHandlerUtil.compareStrIgnoreCaseWithOutEmpty("true", isExist)) {
                String roomNum = resultMap.get("roomNum");
                return new SDKMessageVO(BaseErrorCodeEnum.ERROR.getErrorCode(), roomNum + ",该房间下已有业主", dto.getRequestId(), responseTimestamp, "", isExist);
            }

            //查询新添加住户是否已存在
            Integer resultNum = iPropertyHouseHoldInfoServiceClient.getAppUserExistStatus(dto.getProjectId(), dto.getPhoneNum());
            if (resultNum > 0) {
                return new SDKMessageVO(PropertyErrorCodeEnum.INSPECT_USERINFO_EXIST.getErrorCode(), dto.getRequestId(), responseTimestamp, "");
            }
            //获取住户要添加的房间中已入住的用户人数，再跟项目中设置好的房间最大人数比较，超过则不允许添加
            for (AppUserRoomDTO appUserRoomDTO : appUserRoomDTOS) {
                //当前房间中的住户数量
                Integer currentExistCount =
                        iPropertyHouseHoldInfoServiceClient.getMoveInHouseHoldCount(appUserRoomDTO.getRoomId(), dto.getProjectId());
                //获取该房屋类型 1住宅 2办公
                Integer housesType = iPropertyHouseHoldInfoServiceClient.getHousesType(appUserRoomDTO.getRoomId(), dto.getProjectId());
                //已达到或超过项目中最大授权人数则无法添加住户
                if (housesType == 1 && currentExistCount >= authMaxNum) {
                    return new SDKMessageVO(BaseErrorCodeEnum.ERROR.getErrorCode(), String.format("%s房间中住户人数已达上限", appUserRoomDTO.getRoomNum()) + ",该房间下已有业主", dto.getRequestId(), responseTimestamp, "");
                }
                if (housesType == 3 && currentExistCount >= officeAuthMaxNum) {
                    return new SDKMessageVO(BaseErrorCodeEnum.ERROR.getErrorCode(), String.format("%s房间中住户人数已达上限", appUserRoomDTO.getRoomNum()) + ",该房间下已有业主", dto.getRequestId(), responseTimestamp, "");
                }
            }

            //保存用户数据
            AppUserGetUserInfoDTO appUserGetUserInfoDTO = new AppUserGetUserInfoDTO();
            appUserGetUserInfoDTO.setUserId(LogicIdUtil.userBusinessId());
            appUserGetUserInfoDTO.setPhoneNum(dto.getPhoneNum());
            appUserGetUserInfoDTO.setRealName(dto.getRealName());
            appUserGetUserInfoDTO.setGender(dto.getGender());
            appUserGetUserInfoDTO.setProjectId(dto.getProjectId());
            appUserGetUserInfoDTO.setAppUserRoomDTOS(appUserRoomDTOS);
            iPropertyHouseHoldInfoServiceClient.addAppUser(appUserGetUserInfoDTO, projectPO.getIsSmartCommunity(), request.getAttribute("appId").toString());

            Map<String, Object> map = new HashMap<>();
            map.put("userId", appUserGetUserInfoDTO.getUserId());
            if (StringUtils.isNotEmpty(dto.getImageStr())) {
                //判断项目是否开启人脸识别,并查询是否有百度库key
                OperateFaceApplyInfoVO operateFaceApplyInfoVO = iOperateFaceApplyServiceClient.getFaceByProjectId(dto.getProjectId());
                if (operateFaceApplyInfoVO == null) {
                    return new SDKMessageVO(AppErrorCodeEnum.PROJECT_FACE_APPID_INEXISTENCE.getErrorCode(), dto.getRequestId(), responseTimestamp, "");
                }
                AppCreateBaiduFaceVO appCreateBaiduFaceVO = new AppCreateBaiduFaceVO();
                appCreateBaiduFaceVO.setAPP_ID(operateFaceApplyInfoVO.getAppId());
                appCreateBaiduFaceVO.setAPI_KEY(operateFaceApplyInfoVO.getApiKey());
                appCreateBaiduFaceVO.setSECRET_KEY(operateFaceApplyInfoVO.getSecretKey());
                appCreateBaiduFaceVO.setFaceScore(operateFaceApplyInfoVO.getFaceScore() == 0F ? 80F : operateFaceApplyInfoVO.getFaceScore());
                //判断图片分辨率
                BufferedImage bi = ImageIO.read(new ByteArrayInputStream(new BASE64Decoder().decodeBuffer(dto.getImageStr())));
                int width = bi.getWidth();
                int height = bi.getHeight();
                if (width < 640 || height < 480 || width > 2560 || height > 2560) {
                    return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_FACE_RESOLUTION_RATIO_ERROR.getErrorCode(), appCreateBaiduFaceVO.getRequestId(), appCreateBaiduFaceVO.getResponseTimestamp(), "");
                }
                //保存图片
                String uploadFilePath = uploadImageFile(new BASE64Decoder().decodeBuffer(dto.getImageStr()), "png", FileCatalogEnum.BAIDU_FACE_CREATE_FILE);
                appCreateBaiduFaceVO.setImageUrl(uploadFilePath);
                appCreateBaiduFaceVO.setUid(appUserGetUserInfoDTO.getUserId());
                appCreateBaiduFaceVO.setRequestId(dto.getRequestId());
                appCreateBaiduFaceVO.setAppSecret(dto.getAppSecret());
                appCreateBaiduFaceVO.setResponseTimestamp(dto.getResponseTimestamp());

                SDKMessageVO messageVO = this.checkFace(appCreateBaiduFaceVO);
                if (messageVO != null) {
                    messageVO.setData(map);
                    return messageVO;
                }

                //保存数据
                messageVO = this.saveUserFace(appUserGetUserInfoDTO.getUserId(), uploadFilePath, dto, appCreateBaiduFaceVO);
                if (messageVO != null) {
                    messageVO.setData(map);
                    return messageVO;
                }
                // 平板优先离线，则插入同步数据
                PadFaceSyncDataDTO padFaceSyncDataDTO = new PadFaceSyncDataDTO();
                padFaceSyncDataDTO.setOperateType("1");
                padFaceSyncDataDTO.setAppUserIds(appUserGetUserInfoDTO.getUserId());
                padFaceSyncDataDTO.setProjectId(dto.getProjectId());
                padFaceSyncDataDTO.setStatus("1");
                padFaceSyncDataDTO.setSourceSystem(4);
                iPadFaceSyncDataServiceClient.userOrFloorSync(padFaceSyncDataDTO);
                iPadFaceSyncDataServiceClient.userOrFloorSyncSmartCard(padFaceSyncDataDTO);
            }
            return new SDKMessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), dto.getRequestId(), dto.getResponseTimestamp(),
                    Md5EncryptUtil.getSDKV2Md5(map, dto.getRequestId(), dto.getResponseTimestamp(), dto.getAppSecret()), map);
        } catch (Exception e) {
            request.setAttribute("exception", e.toString());
            throw new DataAccessException("【SDK_人脸识别API_addUserBindRoom】添加用户并绑定房间的关系异常", e);
        }
    }

    /**
     * <desc>
     * 修改用户信息
     * <desc/>
     *
     * @return Object   标准格式化响应结果
     * @author Qiang.S
     * @createDate 2019/11/05
     */
    @ResponseBody
    @RequestMapping("/updateUserInfo")
    @LoggerInfo(operateDesc = LogDescConstant.SDK_FACE_UPDATE_USER_INFO_LOG_DESC)
    public Object updateUserInfo() {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        try {
            CloudFaceApiDTO dto = HttpProtocolUtil.parseRequestParamToDTO(CloudFaceApiDTO.class, request);
            //保存生成操作日志所需信息 详细描述和接口类别
            //解决上传参数中有图片使操作日志写不了库
            Map map1 = SqlUtil.convertBeanToMapParams(dto);
            map1.put("imageStr","");
            request.setAttribute("remark",map1.toString());
            request.setAttribute("portType", LogDescConstant.SDK_CLOUD_DEVICE_TYPE_LOG_DESC);

            String responseTimestamp = new Date().getTime() + "";
            if (StringUtils.isEmpty(dto.getProjectId()) || StringUtils.isEmpty(dto.getRealName())
                    || (dto.getGender() != null && (dto.getGender() != 1 && dto.getGender() != 0)) || StringUtils.isEmpty(dto.getUserId())) {
                return new SDKMessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode(), dto.getRequestId(), responseTimestamp, "");
            }
            //权限判断
            OperateDeveloperAuthDeviceAuthListDTO operateDeveloperAuthDeviceAuthListDTO = new OperateDeveloperAuthDeviceAuthListDTO();
            operateDeveloperAuthDeviceAuthListDTO.setUserId(request.getAttribute("appId").toString());
            operateDeveloperAuthDeviceAuthListDTO.setProjectId(dto.getProjectId());
            OperateDeveloperAuthDeviceAuthVO operateDeveloperAuthDeviceAuthVO = iOperateDeveloperAuthServiceClient.deviceAuthList(operateDeveloperAuthDeviceAuthListDTO);
            if (StringUtils.isNotEmpty(dto.getImageStr()) && (operateDeveloperAuthDeviceAuthVO == null || operateDeveloperAuthDeviceAuthVO.getFaceRecognitionApi() != 1)) {//没有权限
                return new SDKMessageVO(SDKErrorCodeEnum.SDK_FACE_API_AUTHORITY_ERR.getErrorCode(), dto.getRequestId(), responseTimestamp, "");
            }
            if (StringUtils.isNotBlank(dto.getPhoneNum())) {
                String regex = "^1[3|4|5|6|7|8|9]\\d{9}$";
                if (dto.getPhoneNum().length() != 11 || !Pattern.compile(regex).matcher(dto.getPhoneNum()).matches()) {
                    return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_PHONENUM_ERR.getErrorCode(), dto.getRequestId(), responseTimestamp, "");
                }
                //查询手机号是否存在
                Integer result = iPropertyHouseHoldInfoServiceClient.getAppUserExistStatus(dto.getProjectId(), dto.getPhoneNum());
                if (result > 0) {
                    return new SDKMessageVO(AppErrorCodeEnum.EXIST_PHONENO.getErrorCode(), dto.getRequestId(), responseTimestamp, "");
                }
            }
            iPropertyHouseHoldInfoServiceClient.updateUserInfo(dto);
            if (StringUtils.isNotBlank(dto.getImageStr())) {//重新认证
                //判断项目是否开启人脸识别,并查询是否有百度库key
                OperateFaceApplyInfoVO operateFaceApplyInfoVO = iOperateFaceApplyServiceClient.getFaceByProjectId(dto.getProjectId());
                if (operateFaceApplyInfoVO == null) {
                    return new SDKMessageVO(AppErrorCodeEnum.PROJECT_FACE_APPID_INEXISTENCE.getErrorCode(), dto.getRequestId(), responseTimestamp, "");
                }
                AppCreateBaiduFaceVO appCreateBaiduFaceVO = new AppCreateBaiduFaceVO();
                appCreateBaiduFaceVO.setAPP_ID(operateFaceApplyInfoVO.getAppId());
                appCreateBaiduFaceVO.setAPI_KEY(operateFaceApplyInfoVO.getApiKey());
                appCreateBaiduFaceVO.setSECRET_KEY(operateFaceApplyInfoVO.getSecretKey());
                appCreateBaiduFaceVO.setFaceScore(operateFaceApplyInfoVO.getFaceScore() == 0F ? 80F : operateFaceApplyInfoVO.getFaceScore());
                //判断图片分辨率
                BufferedImage bi = ImageIO.read(new ByteArrayInputStream(new BASE64Decoder().decodeBuffer(dto.getImageStr())));
                int width = bi.getWidth();
                int height = bi.getHeight();
                if (width < 640 || height < 480 || width > 2560 || height > 2560) {
                    return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_FACE_RESOLUTION_RATIO_ERROR.getErrorCode(), appCreateBaiduFaceVO.getRequestId(), appCreateBaiduFaceVO.getResponseTimestamp(), "");
                }
                //保存图片
                String uploadFilePath = uploadImageFile(new BASE64Decoder().decodeBuffer(dto.getImageStr()), "png", FileCatalogEnum.BAIDU_FACE_CREATE_FILE);
                appCreateBaiduFaceVO.setImageUrl(uploadFilePath);
                appCreateBaiduFaceVO.setUid(dto.getUserId());

                //人脸判断
                SDKMessageVO messageVO = this.checkFace(appCreateBaiduFaceVO);
                if (messageVO != null) {
                    return messageVO;
                }
                //保存数据
                messageVO = this.saveUserFace(dto.getUserId(), uploadFilePath, dto, appCreateBaiduFaceVO);
                if (messageVO != null) {
                    return messageVO;
                }
                PadFaceSyncDataDTO padFaceSyncDataDTO = new PadFaceSyncDataDTO();
                padFaceSyncDataDTO.setOperateType("1");
                padFaceSyncDataDTO.setAppUserIds(dto.getUserId());
                padFaceSyncDataDTO.setProjectId(dto.getProjectId());
                padFaceSyncDataDTO.setStatus("1");
                padFaceSyncDataDTO.setSourceSystem(4);
                iPadFaceSyncDataServiceClient.userOrFloorSync(padFaceSyncDataDTO);
                iPadFaceSyncDataServiceClient.userOrFloorSyncSmartCard(padFaceSyncDataDTO);
            }
            return new SDKMessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), dto.getRequestId(), responseTimestamp,
                    Md5EncryptUtil.getSDKV2Md5(new HashMap<>(), dto.getRequestId(), responseTimestamp,
                            dto.getAppSecret()));
        } catch (Exception e) {
            request.setAttribute("exception", e.toString());
            throw new DataAccessException("【SDK_人脸识别API_updateUserInfo】修改用户信息异常", e);
        }
    }

    /**
     * <desc>
     * 用户迁入
     * <desc/>
     *
     * @return Object   标准格式化响应结果
     * @author Qiang.S
     * @createDate 2019/11/05
     */
    @ResponseBody
    @RequestMapping("/userMoveIn")
    @LoggerInfo(operateDesc = LogDescConstant.SDK_FACE_USER_MOVE_IN_LOG_DESC)
    public Object userMoveIn() {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        try {
            String responseTimestamp = new Date().getTime() + "";
            if (request.getAttribute("appUsersMovein") == null || request.getAttribute("projectId") == null) {
                return new SDKMessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode(), request.getAttribute("requestId").toString(), responseTimestamp, "");
            }
            String appUsersMovein = request.getAttribute("appUsersMovein").toString();
            String projectId = request.getAttribute("projectId").toString();
            //保存生成操作日志所需信息 详细描述和接口类别
            request.setAttribute("remark", appUsersMovein + "|" + projectId);
            request.setAttribute("portType", LogDescConstant.SDK_CLOUD_FACE_RECOGNITION_TYPE_LOG_DESC);
            //权限判断
//            OperateDeveloperAuthDeviceAuthListDTO operateDeveloperAuthDeviceAuthListDTO = new OperateDeveloperAuthDeviceAuthListDTO();
//            operateDeveloperAuthDeviceAuthListDTO.setUserId(request.getAttribute("appId").toString());
//            operateDeveloperAuthDeviceAuthListDTO.setProjectId(projectId);
//            OperateDeveloperAuthDeviceAuthVO operateDeveloperAuthDeviceAuthVO = iOperateDeveloperAuthServiceClient.deviceAuthList(operateDeveloperAuthDeviceAuthListDTO);
//            if (operateDeveloperAuthDeviceAuthVO == null || operateDeveloperAuthDeviceAuthVO.getFaceRecognitionApi() != 1) {//没有权限
//                return new SDKMessageVO(SDKErrorCodeEnum.SDK_FACE_API_AUTHORITY_ERR.getErrorCode(),request.getAttribute("requestId").toString(),responseTimestamp,"");
//            }
            //解析传入的需迁入的App用户信息
            AppUserUpdateUserRoomStatusDTO appUserUpdateUserRoomStatusDTO;
            try {
                appUserUpdateUserRoomStatusDTO = JSON.parseObject(appUsersMovein, AppUserUpdateUserRoomStatusDTO.class);
            } catch (Exception e) {
                return new SDKMessageVO(SDKErrorCodeEnum.SDK_INPUT_PARAM_ERR.getErrorCode(), request.getAttribute("requestId").toString(), responseTimestamp, "");
            }
            appUserUpdateUserRoomStatusDTO.setProjectId(projectId);
            List<AppUsersRemoveDTO> appUsersRemoveDTOS = appUserUpdateUserRoomStatusDTO.getAppUsersRemoveDTOList();
            if (appUsersRemoveDTOS.isEmpty()) {
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_USERROOM_NOT_NULL.getErrorCode(), request.getAttribute("requestId").toString(), responseTimestamp, "");
            }
            //查询当前项目信息
            ProjectPO projectPO = iOperateProjectServiceClient.getOneProject(projectId);
            //是否启用云对讲，默认0,0-否，1-是
            Integer isSmartCommunity = projectPO.getIsSmartCommunity();
            //住宅最大授权数，最大为10
            Integer authMaxNum = projectPO.getAuthMaxNum();
            //办公最大授权数，最大为500
            Integer officeAuthMaxNum = projectPO.getOfficeAuthMaxNum();
            if (officeAuthMaxNum == 0) {
                officeAuthMaxNum = 11;
            }
            //判断迁入住户业主房间地址中是否已存在业主
            Set<String> userIds = new HashSet<>();
            for (AppUsersRemoveDTO appUsersRemoveDTO : appUsersRemoveDTOS) {
                //住户userId
                String userId = appUsersRemoveDTO.getUserId();
                //住户项目数据状态正常时，若住户已被冻结，则无法迁入
                Integer userProjectStatus = iPropertyHouseHoldInfoServiceClient.getUserProjectStatusAtNormal(projectId, userId);
                if (AppUserProjectStatusEnum.USERPROJECT_USERPROJECTSTATUS_FROZEN.getType() == userProjectStatus) {
                    return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_USERPROJECTSTATUS_FROZEN.getErrorCode(), request.getAttribute("requestId").toString(), responseTimestamp, "");
                }
                List<AppUserRoomDTO> appUserRoomDTOS = appUsersRemoveDTO.getAppUserRoomDTOS();
                //Map<String, value> ：isExist业主是否存在，roomNum 业主存在时的房间号,userId 业主userId
                Map<String, String> resultMap = this.checkOwnerExist(appUserRoomDTOS);
                String isExist = resultMap.get("isExist");
                //房间存在业主，且房间中的业主与当前用户不是同一人时才不允许添加
                if (StringHandlerUtil.compareStrWithOutEmpty("true", isExist) &&
                        !StringHandlerUtil.compareStrWithOutEmpty(userId, resultMap.get("userId"))) {
                    String roomNum = resultMap.get("roomNum");
                    return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_USERPROJECTSTATUS_FROZEN.getErrorCode(), roomNum + ",该房间下已有业主或管理员", request.getAttribute("requestId").toString(), responseTimestamp, "", isExist);
                }
                //获取住户要添加的房间中已入住的用户人数，再跟项目中设置好的房间最大人数比较，超过则不允许添加
                for (AppUserRoomDTO appUserRoomDTO : appUserRoomDTOS) {
                    //当前房间中的住户数量
                    Integer currentExistCount =
                            iPropertyHouseHoldInfoServiceClient.getMoveInHouseHoldCount(appUserRoomDTO.getRoomId(), projectId);
                    //获取该房屋类型 1住宅 2办公
                    Integer housesType = iPropertyHouseHoldInfoServiceClient.getHousesType(appUserRoomDTO.getRoomId(), projectId);
                    //已达到或超过项目中最大授权人数则无法添加住户
                    if (housesType == 1 && currentExistCount >= authMaxNum) {
                        return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_USERPROJECTSTATUS_FROZEN.getErrorCode(), String.format("%s房间中住户人数已达上限", appUserRoomDTO.getRoomNum()), request.getAttribute("requestId").toString(), responseTimestamp, "");
                    }
                    if (housesType == 3 && currentExistCount >= officeAuthMaxNum) {
                        return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_USERPROJECTSTATUS_FROZEN.getErrorCode(), String.format("%s房间中住户人数已达上限", appUserRoomDTO.getRoomNum()), request.getAttribute("requestId").toString(), responseTimestamp, "");
                    }
                }
                userIds.add(userId);
            }

            //迁入App用户信息
            iPropertyHouseHoldInfoServiceClient.userMoveIn(appUserUpdateUserRoomStatusDTO, isSmartCommunity,
                    request.getAttribute("appId").toString(), HouseHoldJPushSceneTypeEnum.HOUSEHOLD_J_PUSH_SCENE_TYPE_MOVE_IN.getType());
            return new SDKMessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), request.getAttribute("requestId").toString(), responseTimestamp,
                    Md5EncryptUtil.getSDKV2Md5(new HashMap<>(), request.getAttribute("requestId").toString(), responseTimestamp,
                            request.getAttribute("appSecret").toString()));
        } catch (Exception e) {
            request.setAttribute("exception", e.toString());
            throw new DataAccessException("【SDK_人脸识别API_userMoveIn】用户迁入异常", e);
        }
    }

    /**
     * <desc>
     * 用户迁出
     * <desc/>
     *
     * @return Object   标准格式化响应结果
     * @author Qiang.S
     * @createDate 2019/11/05
     */
    @ResponseBody
    @RequestMapping("/userRemove")
    @LoggerInfo(operateDesc = LogDescConstant.SDK_FACE_USER_REMOVE_LOG_DESC)
    public Object userRemove() {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        try {
            String responseTimestamp = new Date().getTime() + "";
            if (request.getAttribute("appUsersRemove") == null || request.getAttribute("projectId") == null) {
                return new SDKMessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode(), request.getAttribute("requestId").toString(), responseTimestamp, "");
            }
            String appUsersRemove = request.getAttribute("appUsersRemove").toString();
            String projectId = request.getAttribute("projectId").toString();
            //保存生成操作日志所需信息 详细描述和接口类别
            request.setAttribute("remark", appUsersRemove + "|" + projectId);
            request.setAttribute("portType", LogDescConstant.SDK_CLOUD_FACE_RECOGNITION_TYPE_LOG_DESC);
            //权限判断
//            OperateDeveloperAuthDeviceAuthListDTO operateDeveloperAuthDeviceAuthListDTO = new OperateDeveloperAuthDeviceAuthListDTO();
//            operateDeveloperAuthDeviceAuthListDTO.setUserId(request.getAttribute("appId").toString());
//            operateDeveloperAuthDeviceAuthListDTO.setProjectId(projectId);
//            OperateDeveloperAuthDeviceAuthVO operateDeveloperAuthDeviceAuthVO = iOperateDeveloperAuthServiceClient.deviceAuthList(operateDeveloperAuthDeviceAuthListDTO);
//            if (operateDeveloperAuthDeviceAuthVO == null || operateDeveloperAuthDeviceAuthVO.getFaceRecognitionApi() != 1) {//没有权限
//                return new SDKMessageVO(SDKErrorCodeEnum.SDK_FACE_API_AUTHORITY_ERR.getErrorCode(),request.getAttribute("requestId").toString(),responseTimestamp,"");
//            }
            //解析JSON数据
            AppUserUpdateUserRoomStatusDTO appUserUpdateUserRoomStatusDTO;
            try {
                appUserUpdateUserRoomStatusDTO = JSON.parseObject(appUsersRemove, AppUserUpdateUserRoomStatusDTO.class);
            } catch (Exception e) {
                return new SDKMessageVO(SDKErrorCodeEnum.SDK_INPUT_PARAM_ERR.getErrorCode(), request.getAttribute("requestId").toString(), responseTimestamp, "");
            }
            //迁出用户信息不能为空
            if (appUserUpdateUserRoomStatusDTO == null) {
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_USERREMEVO_NOT_NULL.getErrorCode(), request.getAttribute("requestId").toString(), responseTimestamp, "");
            }
            List<AppUsersRemoveDTO> appUsersRemoveDTOS = appUserUpdateUserRoomStatusDTO.getAppUsersRemoveDTOList();
            if (appUsersRemoveDTOS == null || appUsersRemoveDTOS.size() < 1) {
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_USERROOM_NOT_NULL.getErrorCode(), request.getAttribute("requestId").toString(), responseTimestamp, "");
            }
            Set<String> userIds = new HashSet<>();
            for (AppUsersRemoveDTO appUsersRemoveDTO : appUsersRemoveDTOS) {
                String userId = appUsersRemoveDTO.getUserId();
                //住户项目数据状态正常时，若住户已被冻结，则无法迁入
                Integer userProjectStatus = iPropertyHouseHoldInfoServiceClient.getUserProjectStatusAtNormal(projectId, userId);
                if (AppUserProjectStatusEnum.USERPROJECT_USERPROJECTSTATUS_FROZEN.getType() == userProjectStatus) {
                    return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_USERPROJECTSTATUS_FROZEN.getErrorCode(), request.getAttribute("requestId").toString(), responseTimestamp, "");
                }
                userIds.add(userId);
            }
            //查询当前项目信息
            ProjectPO projectPO = iOperateProjectServiceClient.getOneProject(projectId);
            //是否使用云对讲： 0-否，1-是
            Integer isSmartCommunity = projectPO.getIsSmartCommunity();

            appUserUpdateUserRoomStatusDTO.setProjectId(projectId);
            appUserUpdateUserRoomStatusDTO.setInstructionType(2);
            appUserUpdateUserRoomStatusDTO.setSourceSystem(4);
            iPropertyHouseHoldInfoServiceClient.userRemove(appUserUpdateUserRoomStatusDTO, isSmartCommunity,
                    request.getAttribute("appId").toString(), HouseHoldJPushSceneTypeEnum.HOUSEHOLD_J_PUSH_SCENE_TYPE_MOVE_OUT.getType());
            return new SDKMessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), request.getAttribute("requestId").toString(), responseTimestamp,
                    Md5EncryptUtil.getSDKV2Md5(new HashMap<>(), request.getAttribute("requestId").toString(), responseTimestamp,
                            request.getAttribute("appSecret").toString()));
        } catch (Exception e) {
            request.setAttribute("exception", e.toString());
            throw new DataAccessException("【SDK_人脸识别API_userRemove】用户迁出异常", e);
        }
    }

    /**
     * <desc>
     * 冻结/解冻用户状态
     * <desc/>
     *
     * @return MessageVO 标准格式化响应结果
     * @author Qiang.S
     * @createDate 2019/11/05
     */
    @UnAuthAccessRequired
    public Object modifyUserStatus(AppUserUpdateUserProjectStatusDTO appUserUpdateUserProjectStatusDTO) throws Exception {
        if (StringUtils.isEmpty(appUserUpdateUserProjectStatusDTO.getUserIds())
                || StringUtils.isEmpty(appUserUpdateUserProjectStatusDTO.getUserProjectStatus()) || (!"0".equals(appUserUpdateUserProjectStatusDTO.getUserProjectStatus()) &&
                !"1".equals(appUserUpdateUserProjectStatusDTO.getUserProjectStatus()))) {
            return new SDKMessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode(), appUserUpdateUserProjectStatusDTO.getRequestId(), appUserUpdateUserProjectStatusDTO.getResponseTimestamp(), "");
        }
        //查询当前项目信息
        ProjectPO projectPO = iOperateProjectServiceClient.getOneProject(appUserUpdateUserProjectStatusDTO.getProjectId());
        appUserUpdateUserProjectStatusDTO.setProjectName(projectPO.getProjectName());
        appUserUpdateUserProjectStatusDTO.setIsSmartCommunity(projectPO.getIsSmartCommunity());
        appUserUpdateUserProjectStatusDTO.setInstructionType(0);
        appUserUpdateUserProjectStatusDTO.setSourceSystem(4);
        //更新用户项目状态
        iPropertyHouseHoldInfoServiceClient.userProjectStatus(appUserUpdateUserProjectStatusDTO);
        // 平板优先离线，则插入同步数据
        if (projectPO.getOnOffLinePadFace() != null) {
            PadFaceSyncDataDTO padFaceSyncDataDTO = new PadFaceSyncDataDTO();
            padFaceSyncDataDTO.setOperateType("0");
            padFaceSyncDataDTO.setAppUserIds(appUserUpdateUserProjectStatusDTO.getUserIds());
            padFaceSyncDataDTO.setProjectId(appUserUpdateUserProjectStatusDTO.getProjectId());
            padFaceSyncDataDTO.setSourceSystem(4);
            // 用户禁用启用状态 1正常 5禁用 4冻结 2欠费
            if (projectPO.getOnOffLinePadFace() == 1) {
                padFaceSyncDataDTO.setStatus("1".equals(appUserUpdateUserProjectStatusDTO.getUserProjectStatus()) ? "1" : "4");
                iPadFaceSyncDataServiceClient.userOrFloorSync(padFaceSyncDataDTO);
            }
            padFaceSyncDataDTO.setStatus("1".equals(appUserUpdateUserProjectStatusDTO.getUserProjectStatus()) ? "1" : "2");
            iPadFaceSyncDataServiceClient.userOrFloorSyncSmartCard(padFaceSyncDataDTO);
        }
        return new SDKMessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), appUserUpdateUserProjectStatusDTO.getRequestId(), appUserUpdateUserProjectStatusDTO.getResponseTimestamp(),
                Md5EncryptUtil.getSDKV2Md5(new HashMap<>(), appUserUpdateUserProjectStatusDTO.getRequestId(), appUserUpdateUserProjectStatusDTO.getResponseTimestamp(),
                        appUserUpdateUserProjectStatusDTO.getAppSecret()));
    }

    /**
     * <desc>
     * 查询用户列表
     * <desc/>
     *
     * @return MessageVO 标准格式化响应结果
     * @author Qiang.S
     * @createDate 2019/11/05
     */
    @LoggerInfo(operateDesc = LogDescConstant.SDK_FACE_USER_INFO_LOG_DESC)
    @RequestMapping(path = "/getUserInfo", method = RequestMethod.POST)
    @ResponseBody
    public Object getUserInfo() {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        try {
            CloudFaceApiDTO dto = HttpProtocolUtil.parseRequestParamToDTO(CloudFaceApiDTO.class, request);
            //保存生成操作日志所需信息 详细描述和接口类别
            request.setAttribute("remark", dto.toString());
            request.setAttribute("portType", LogDescConstant.SDK_CLOUD_FACE_RECOGNITION_TYPE_LOG_DESC);

            String responseTimestamp = new Date().getTime() + "";
            if (StringUtils.isEmpty(dto.getProjectId())) {
                return new SDKMessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode(), dto.getRequestId(), responseTimestamp, "");
            }
            dto.setPageSize(request.getAttribute("pageSize") == null ? null : request.getAttribute("pageSize").toString());
            dto.setCurrentPage(request.getAttribute("currentPage") == null ? null : request.getAttribute("currentPage").toString());
            if (StringUtils.isBlank(dto.getCurrentPage())) {
                dto.setCurrentPage("1");
            }
            if (StringUtils.isBlank(dto.getPageSize())) {
                dto.setPageSize("15");
            }
            //权限判断
//            OperateDeveloperAuthDeviceAuthListDTO operateDeveloperAuthDeviceAuthListDTO = new OperateDeveloperAuthDeviceAuthListDTO();
//            operateDeveloperAuthDeviceAuthListDTO.setUserId(request.getAttribute("appId").toString());
//            operateDeveloperAuthDeviceAuthListDTO.setProjectId(dto.getProjectId());
//            OperateDeveloperAuthDeviceAuthVO operateDeveloperAuthDeviceAuthVO = iOperateDeveloperAuthServiceClient.deviceAuthList(operateDeveloperAuthDeviceAuthListDTO);
//            if (operateDeveloperAuthDeviceAuthVO == null || operateDeveloperAuthDeviceAuthVO.getFaceRecognitionApi() != 1) {//没有权限
//                return new SDKMessageVO(SDKErrorCodeEnum.SDK_FACE_API_AUTHORITY_ERR.getErrorCode(),dto.getRequestId(),responseTimestamp,"");
//            }

            Page<SDKFaceUserInfoGetVO> result = iPropertyHouseHoldInfoServiceClient.getUserInfoForApi(dto);
            Page<SDKUserInfoGetAssembleVO> page = new Page<>();
            page.setPage(result.getPage());
            page.setRows(this.assembleApiUserInfoGetVO(result.getRows()));
            return new SDKMessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), dto.getRequestId(), dto.getResponseTimestamp(),
                    Md5EncryptUtil.getSDKV2Md5(new HashMap<>(), dto.getRequestId(), dto.getResponseTimestamp(), dto.getAppSecret()), page);
        } catch (Exception e) {
            request.setAttribute("exception", e.toString());
            throw new DataAccessException("【SDK_人脸识别API_getUserInfo】查询用户列表异常", e);
        }
    }

    /**
     * <desc>
     * 查询设备列表
     * <desc/>
     *
     * @return MessageVO 标准格式化响应结果
     * @author Qiang.S
     * @createDate 2019/11/06
     */
    //@LoggerInfo(operateDesc = LogDescConstant.SDK_FACE_DEVICE_INFO_LOG_DESC)
    @RequestMapping(path = "/getDeviceInfo", method = RequestMethod.POST)
    @ResponseBody
    public Object getDeviceInfo() {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        try {
            CloudFaceApiDTO dto = HttpProtocolUtil.parseRequestParamToDTO(CloudFaceApiDTO.class, request);
            //保存生成操作日志所需信息 详细描述和接口类别
            request.setAttribute("remark", dto.toString());
            request.setAttribute("portType", LogDescConstant.SDK_CLOUD_FACE_RECOGNITION_TYPE_LOG_DESC);

            String responseTimestamp = new Date().getTime() + "";
            if (StringUtils.isEmpty(dto.getProjectId())) {
                return new SDKMessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode(), dto.getRequestId(), responseTimestamp, "");
            }
            //权限判断
            OperateDeveloperAuthDeviceAuthListDTO operateDeveloperAuthDeviceAuthListDTO = new OperateDeveloperAuthDeviceAuthListDTO();
            operateDeveloperAuthDeviceAuthListDTO.setUserId(request.getAttribute("appId").toString());
            operateDeveloperAuthDeviceAuthListDTO.setProjectId(dto.getProjectId());
            OperateDeveloperAuthDeviceAuthVO operateDeveloperAuthDeviceAuthVO = iOperateDeveloperAuthServiceClient.deviceAuthList(operateDeveloperAuthDeviceAuthListDTO);
            if (operateDeveloperAuthDeviceAuthVO == null || operateDeveloperAuthDeviceAuthVO.getFaceRecognitionApi() != 1) {//没有权限
                return new SDKMessageVO(SDKErrorCodeEnum.SDK_FACE_API_AUTHORITY_ERR.getErrorCode(), dto.getRequestId(), responseTimestamp, "");
            }
            List<SDKFaceDeviceInfoGetVO> result = iPropertyEquipServiceClient.getEquipInfoForApi(dto);
            return new SDKMessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), dto.getRequestId(), dto.getResponseTimestamp(),
                    Md5EncryptUtil.getSDKV2Md5(new HashMap<>(), dto.getRequestId(), dto.getResponseTimestamp(), dto.getAppSecret()), this.assembleApiDeviceInfoGetVO(result));
        } catch (Exception e) {
            request.setAttribute("exception", e.toString());
            throw new DataAccessException("【SDK_人脸识别API_getDeviceInfo】查询设备列表异常", e);
        }
    }

    /**
     * <desc>
     * 查询多媒体列表
     * <desc/>
     *
     * @return MessageVO 标准格式化响应结果
     * @author Qiang.S
     * @createDate 2019/11/06
     */
    //@LoggerInfo(operateDesc = LogDescConstant.SDK_FACE_MEDIA_INFO_LOG_DESC)
    @RequestMapping(path = "/getMediaInfo", method = RequestMethod.POST)
    @ResponseBody
    public Object getMediaInfo() {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        try {
            CloudFaceApiDTO dto = HttpProtocolUtil.parseRequestParamToDTO(CloudFaceApiDTO.class, request);
            //保存生成操作日志所需信息 详细描述和接口类别
            request.setAttribute("remark", dto.toString());
            request.setAttribute("portType", LogDescConstant.SDK_CLOUD_FACE_RECOGNITION_TYPE_LOG_DESC);

            String responseTimestamp = new Date().getTime() + "";
            if (StringUtils.isEmpty(dto.getProjectId())) {
                return new SDKMessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode(), dto.getRequestId(), responseTimestamp, "");
            }
            //权限判断
            OperateDeveloperAuthDeviceAuthListDTO operateDeveloperAuthDeviceAuthListDTO = new OperateDeveloperAuthDeviceAuthListDTO();
            operateDeveloperAuthDeviceAuthListDTO.setUserId(request.getAttribute("appId").toString());
            operateDeveloperAuthDeviceAuthListDTO.setProjectId(dto.getProjectId());
            OperateDeveloperAuthDeviceAuthVO operateDeveloperAuthDeviceAuthVO = iOperateDeveloperAuthServiceClient.deviceAuthList(operateDeveloperAuthDeviceAuthListDTO);
            if (operateDeveloperAuthDeviceAuthVO == null || operateDeveloperAuthDeviceAuthVO.getFaceRecognitionApi() != 1) {//没有权限
                return new SDKMessageVO(SDKErrorCodeEnum.SDK_FACE_API_AUTHORITY_ERR.getErrorCode(), dto.getRequestId(), responseTimestamp, "");
            }
            DeviceMediaInfoGetPageDTO deviceMediaInfoGetPageDTO = new DeviceMediaInfoGetPageDTO();
            deviceMediaInfoGetPageDTO.setProjectId(dto.getProjectId());
            deviceMediaInfoGetPageDTO.setStatus(dto.getStatus());
            deviceMediaInfoGetPageDTO.setTitle(dto.getTitle());
            deviceMediaInfoGetPageDTO.setDeviceName(dto.getDeviceName());
            deviceMediaInfoGetPageDTO.setPublishStatus(dto.getPublishStatus());
            deviceMediaInfoGetPageDTO.setType(dto.getType());
            deviceMediaInfoGetPageDTO.setPageSize(request.getAttribute("pageSize") == null ? null : request.getAttribute("pageSize").toString());
            deviceMediaInfoGetPageDTO.setCurrentPage(request.getAttribute("currentPage") == null ? null : request.getAttribute("currentPage").toString());
            if (StringUtils.isBlank(dto.getCurrentPage())) {
                deviceMediaInfoGetPageDTO.setCurrentPage("1");
            }
            if (StringUtils.isBlank(dto.getPageSize())) {
                deviceMediaInfoGetPageDTO.setPageSize("15");
            }
            Page<DeviceMediaInfoVO> page = iDeviceMediaInfoServiceClient.getMediaInfoByPage(deviceMediaInfoGetPageDTO);
            return new SDKMessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), dto.getRequestId(), dto.getResponseTimestamp(),
                    Md5EncryptUtil.getSDKV2Md5(new HashMap<>(), dto.getRequestId(), dto.getResponseTimestamp(), dto.getAppSecret()), page);
        } catch (Exception e) {
            request.setAttribute("exception", e.toString());
            throw new DataAccessException("【SDK_人脸识别API_getDeviceInfo】查询设备列表异常", e);
        }
    }

    /**
     * <desc>
     * 保存访客
     * </desc>
     *
     * @return MessageVO 标准格式化响应结果
     * @author Juguang.S
     * @createDate 2019/11/11
     */
    @UnAuthAccessRequired
    public Object addVisitor(PropertyAddVisitorDTO dto) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        SDKMessageVO messageVO;
        try {
            String responseTimestamp = new Date().getTime() + "";
            dto.setResponseTimestamp(responseTimestamp);
            if (dto == null) {
                return new SDKMessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode(), request.getAttribute("requestId").toString(), responseTimestamp, "");
            }
            if (StringUtils.isNotEmpty(dto.getEffectiveTime()) && Integer.parseInt(dto.getEffectiveTime()) > 1440) {
                return new SDKMessageVO(SDKErrorCodeEnum.SDK_FACE_API_VISITOR_TIME_ERR.getErrorCode(), request.getAttribute("requestId").toString(), responseTimestamp, "");
            }
            AppVisitorPassCodeRecordPO po = iPropertyVisitorServiceClient.addVisitor(dto);
            if (dto.getImageStr() != null && !"".equals(dto.getImageStr())) {
                MiniSetVisitPassFaceDTO miniSetVisitPassFaceDTO = new MiniSetVisitPassFaceDTO();
                miniSetVisitPassFaceDTO.setImageStr(dto.getImageStr());
                miniSetVisitPassFaceDTO.setPassId(po.getPassId());
                miniSetVisitPassFaceDTO.setProjectId(dto.getProjectId());
                miniSetVisitPassFaceDTO.setRequestId(dto.getRequestId());
                miniSetVisitPassFaceDTO.setResponseTimestamp(dto.getResponseTimestamp());
                miniSetVisitPassFaceDTO.setAppSecret(dto.getAppSecret());
                messageVO = this.setVisitPassFacePrivate(miniSetVisitPassFaceDTO);
                if (messageVO.getMsgCode() != 0) {
                    iAppVisitorPassCodeRecordServiceClient.deleteVisitorInfo(po.getPassId());
                    return messageVO;
                }
            }
            if (dto.getDeviceType().equals(SdkSourceTypeEnum.FACE_SDK.getType().toString())) {
                return new SDKMessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), dto.getRequestId(), responseTimestamp,
                        Md5EncryptUtil.getSDKV2Md5(new HashMap<>(), dto.getRequestId(), responseTimestamp,
                                dto.getAppSecret()));
            }
            if (dto.getDeviceType().equals(SdkSourceTypeEnum.CLOUD_TALK.getType().toString())) {
                Map<String, Object> resultMap = new HashMap<>();
                resultMap.put("password", po.getPassword());
                resultMap.put("qrcodeStr", po.getQrcodeUrl());
                return new SDKMessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), dto.getRequestId(), dto.getResponseTimestamp(),
                        Md5EncryptUtil.getSDKV2Md5(resultMap, dto.getRequestId(), dto.getResponseTimestamp(), dto.getAppSecret()), resultMap);
            }
            return new SDKMessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), dto.getRequestId(), responseTimestamp,
                    Md5EncryptUtil.getSDKV2Md5(new HashMap<>(), dto.getRequestId(), responseTimestamp,
                            dto.getAppSecret()));
        } catch (Exception e) {
            request.setAttribute("exception", e.toString());
            throw new DataAccessException("【SDK_人脸识别API_addVisitor】保存访客异常", e);
        }

    }

    /**
     * <desc>
     * 访客列表
     * <desc/>
     *
     * @return MessageVO 标准格式化响应结果
     * @author Juguang.S
     * @createDate 2019/11/11
     */
    @ResponseBody
    @PostMapping(path = "/getVisitorInfoByPage")
    public Object getVisitorInfoForFaceApi() throws Exception {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        try {
            PropertyGetVisitorInfoDTO dto = HttpProtocolUtil.parseRequestParamToDTO(PropertyGetVisitorInfoDTO.class, request);
            //保存生成操作日志所需信息 详细描述和接口类别
            request.setAttribute("remark", dto.toString());
            request.setAttribute("portType", LogDescConstant.SDK_CLOUD_FACE_RECOGNITION_TYPE_LOG_DESC);
            String responseTimestamp = new Date().getTime() + "";
            if (dto == null || StringUtils.isEmpty(dto.getProjectId())) {
                return new SDKMessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode(), request.getAttribute("requestId").toString(), responseTimestamp, "");
            }
            //权限判断
            OperateDeveloperAuthDeviceAuthListDTO operateDeveloperAuthDeviceAuthListDTO = new OperateDeveloperAuthDeviceAuthListDTO();
            operateDeveloperAuthDeviceAuthListDTO.setUserId(request.getAttribute("appId").toString());
            operateDeveloperAuthDeviceAuthListDTO.setProjectId(dto.getProjectId());
            OperateDeveloperAuthDeviceAuthVO operateDeveloperAuthDeviceAuthVO = iOperateDeveloperAuthServiceClient.deviceAuthList(operateDeveloperAuthDeviceAuthListDTO);
            if (operateDeveloperAuthDeviceAuthVO == null || operateDeveloperAuthDeviceAuthVO.getFaceRecognitionApi() != 1) {//没有权限
                return new SDKMessageVO(SDKErrorCodeEnum.SDK_FACE_API_AUTHORITY_ERR.getErrorCode(), request.getAttribute("requestId").toString(), responseTimestamp, "");
            }

            return new SDKMessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), request.getAttribute("requestId").toString(), responseTimestamp,
                    Md5EncryptUtil.getSDKV2Md5(new HashMap<>(), request.getAttribute("requestId").toString(), responseTimestamp, request.getAttribute("appSecret").toString()), iFaceSDKVisitorServiceClient.getVisitorInfoForFaceApi(dto));
        } catch (Exception e) {
            request.setAttribute("exception", e.toString());
            throw new DataAccessException("【SDK_人脸识别API_getVisitorInfoByPage】分页获取访客列表异常", e);
        }
    }

    /**
     * <desc>
     * 查询通行记录
     * </desc>
     *
     * @return 标准格式化响应结果
     * @author Juguang.S
     * @createDate 2019/11/11
     */
    @UnAuthAccessRequired
    public Object getPassRecord(CloudDeviceSDKDTO dto) throws Exception {
        // 处理参数
        if (dto.getPageSize() == null || dto.getPageSize().equals("0")) {
            dto.setPageSize("15");
        }
        if (dto.getCurrentPage() == null || dto.getCurrentPage().equals("0")) {
            dto.setCurrentPage("1");
        }
        Page<SDKEquipRecordGetVO> page = isdkServerProjectServiceClient.getPassRecordByPage(dto);
        return new SDKMessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), dto.getRequestId(), dto.getResponseTimestamp(),
                Md5EncryptUtil.getSDKV2Md5(new HashMap<>(), dto.getRequestId(), dto.getResponseTimestamp(), dto.getAppSecret()), page);
    }

    /**
     * <desc>
     * 删除时间段通行记录
     * <desc/>
     *
     * @return MessageVO 标准格式化响应结果
     * @author Qiang.S
     * @createDate 2020/07/02
     */
    @ResponseBody
    @LoggerInfo(operateDesc = LogDescConstant.SDK_FACE_DELETE_RECORD_LOG)
    @PostMapping(path = "/deleteRecordByDate")
    public Object deleteRecordByDate() throws Exception {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        try {
            CloudDeviceSDKDTO dto = HttpProtocolUtil.parseRequestParamToDTO(CloudDeviceSDKDTO.class, request);
            //保存生成操作日志所需信息 详细描述和接口类别
            request.setAttribute("remark", dto.toString());
            request.setAttribute("portType", LogDescConstant.SDK_CLOUD_FACE_RECOGNITION_TYPE_LOG_DESC);
            String responseTimestamp = new Date().getTime() + "";
            if (dto == null || StringUtils.isEmpty(dto.getProjectId()) || StringUtils.isEmpty(dto.getStartTime()) || StringUtils.isEmpty(dto.getEndTime())) {
                return new SDKMessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode(), request.getAttribute("requestId").toString(), responseTimestamp, "");
            }
            isdkServerProjectServiceClient.deleteRecordByDate(dto);

            return new SDKMessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), request.getAttribute("requestId").toString(), responseTimestamp,
                    Md5EncryptUtil.getSDKV2Md5(new HashMap<>(), request.getAttribute("requestId").toString(), responseTimestamp, request.getAttribute("appSecret").toString()));
        } catch (Exception e) {
            request.setAttribute("exception", e.toString());
            throw new DataAccessException("【SDK_人脸识别API_deleteRecordByDate】删除时间段通行记录异常", e);
        }
    }

    /**
     * <desc>
     * 删除用户信息
     * <desc/>
     *
     * @return MessageVO 标准格式化响应结果
     * @author Qiang.S
     * @createDate 2020/07/02
     */
    @ResponseBody
    @LoggerInfo(operateDesc = LogDescConstant.SDK_FACE_DELETE_USER_LOG)
    @PostMapping(path = "/logOffUser")
    public Object logOffUser() throws Exception {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        try {
            CloudFaceApiDTO dto = HttpProtocolUtil.parseRequestParamToDTO(CloudFaceApiDTO.class, request);
            //保存生成操作日志所需信息 详细描述和接口类别
            request.setAttribute("remark", dto.toString());
            request.setAttribute("portType", LogDescConstant.SDK_CLOUD_FACE_RECOGNITION_TYPE_LOG_DESC);
            String responseTimestamp = new Date().getTime() + "";
            if (dto == null || StringUtils.isEmpty(dto.getProjectId()) || StringUtils.isEmpty(dto.getUserId())) {
                return new SDKMessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode(), request.getAttribute("requestId").toString(), responseTimestamp, "");
            }
            new Thread(() -> {
                try {
                    //清除人脸以及ftp照片
                    iIotVisitorFaceServiceClient.deleteUserFace(dto.getUserId());
                    //优先处理平板指令
                    iPadFaceSyncDataServiceClient.userSyncForSDK(dto.getUserId());
                    //注销用户发送设备端指令
                    iAppMineServiceClient.logOffUserForSDK(dto.getUserId());
                } catch (Exception e) {
                    LOG.error("SDK删除用户处理异常");
                }
            }
            ).start();

            return new SDKMessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), request.getAttribute("requestId").toString(), responseTimestamp,
                    Md5EncryptUtil.getSDKV2Md5(new HashMap<>(), request.getAttribute("requestId").toString(), responseTimestamp, request.getAttribute("appSecret").toString()));
        } catch (Exception e) {
            request.setAttribute("exception", e.toString());
            throw new DataAccessException("【SDK_人脸识别API_logOffUser】删除用户信息异常", e);
        }
    }

    /**
     * <desc>
     * 获取人脸平板或者一体式人脸识别仪 设备在线状态 设备类型：1云对讲 3人脸平板  7一体式人脸识别仪
     * </desc>
     *
     * @Author chengshican
     * @Date 2020-09-23 19:09
     * @Param  DeviceType 3 或者7
     * @Return
     * @Exception
     */
    @UnAuthAccessRequired
    public Object getFaceRecognitionStatus(CloudDeviceSDKDTO dto) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        ArrayList<Map<String, Object>> list = new ArrayList<>();
        List<String> paramList=null;
        if (dto.getDeviceUnique().length()!=0){
            paramList=Arrays.asList(dto.getDeviceUnique());
        }
        Map<String, Object> paramMap = new HashMap<>();
        for(String a :paramList){
            paramMap.put(a,a);
        }
        try {
            //传入设备id，一个或者多个，和设备类型 一体式人脸识别平板
            OperateDeviceManageGetPageDTO operateDeviceManageGetPageDTO = new OperateDeviceManageGetPageDTO();
            if (dto.getDeviceType() != null && "7".equals(dto.getDeviceType())) {//一体式人脸识别仪
                operateDeviceManageGetPageDTO.setDeviceType("7");
            } else if (dto.getDeviceType() != null && "8".equals(dto.getDeviceType())) {//人脸平板
                operateDeviceManageGetPageDTO.setDeviceType("3");
            }
            operateDeviceManageGetPageDTO.setDeviceUnique(dto.getDeviceUnique());
            LOG.info("======getFaceRecognitionStatus获取人脸平板或者一体式人脸识别仪============入参================>{}",operateDeviceManageGetPageDTO.toString());
            OperateDeviceManageInfoAllVO  deviceByPage = iOperateDeviceManageServiceClient.getDeviceByPage(operateDeviceManageGetPageDTO);
            Page<OperateDeviceManageInfoVO> page = deviceByPage.getPage();
            if (page.getRows().size()!=0){
                List<OperateDeviceManageInfoVO> rows = page.getRows();
                for (OperateDeviceManageInfoVO OperateDeviceManageInfoVO : rows) {
                    if (paramMap.containsKey(OperateDeviceManageInfoVO.getDeviceUnique())) {
                        Map<String, Object> map = new HashMap<>();
                        map.put("deviceName", OperateDeviceManageInfoVO.getDeviceName());
                        map.put("deviceUnique", OperateDeviceManageInfoVO.getDeviceUnique());
                        map.put("isOnline", OperateDeviceManageInfoVO.getIsOnline());
                        list.add(map);
                    }
                }
            }
        } catch (Exception e) {
            request.setAttribute("exception", e.toString());
            throw new DataAccessException("【SDK_人脸平板或者一体式人脸识别仪getFaceRecognitionStatus】获取在线状态失败", e);
        }
        Map<String, Object> signMap = new HashMap<>();
        signMap.put("data", JSON.toJSONString(list));
        LOG.info("======getFaceRecognitionStatus获取人脸平板或者一体式人脸识别仪============出参================>{}",signMap.toString());
        return new SDKMessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), dto.getRequestId(), dto.getResponseTimestamp(),
                Md5EncryptUtil.getSDKV2Md5(signMap, dto.getRequestId(), dto.getResponseTimestamp(), dto.getAppSecret()), list);
    }


    /**
     * <desc>
     * 组装查询用户信息返回
     * <desc/>
     *
     * @param sdkFaceUserInfoGetVOS 住户信息对象
     * @return List<SDKUserInfoGetAssembleVO> 组装过的物业住户信息
     * @author Qiang.S
     * @createDate 2019/11/06
     */
    private List<SDKUserInfoGetAssembleVO> assembleApiUserInfoGetVO(List<SDKFaceUserInfoGetVO> sdkFaceUserInfoGetVOS) {
        //返回结果
        List<SDKUserInfoGetAssembleVO> sdkUserInfoGetAssembleVOS = new ArrayList<>();
        //用于组装合并数据
        LinkedHashMap<String, SDKUserInfoGetAssembleVO> linkedHashMap = new LinkedHashMap<>();
        //记录住户
        LinkedHashSet<String> userIdSet = new LinkedHashSet<>();
        if (sdkFaceUserInfoGetVOS.isEmpty()) {
            return sdkUserInfoGetAssembleVOS;
        }
        //遍历
        for (SDKFaceUserInfoGetVO sdkFaceUserInfoGetVO : sdkFaceUserInfoGetVOS) {
            String userId = sdkFaceUserInfoGetVO.getUserId();
            userIdSet.add(userId);
            //相同住户合并住户房间信息
            if (linkedHashMap.get(userId) == null) {
                List<SDKUserInfoGetRoomVO> sdkUserInfoGetRoomVOS = new ArrayList<>();
                SDKUserInfoGetRoomVO sdkUserInfoGetRoomVO = new SDKUserInfoGetRoomVO();
                BeanUtils.copyProperties(sdkFaceUserInfoGetVO, sdkUserInfoGetRoomVO);
                sdkUserInfoGetRoomVOS.add(sdkUserInfoGetRoomVO);
                SDKUserInfoGetAssembleVO sdkUserInfoGetAssembleVO =
                        new SDKUserInfoGetAssembleVO(userId, sdkFaceUserInfoGetVO.getRealName(), sdkFaceUserInfoGetVO.getPhoneNum(),
                                sdkFaceUserInfoGetVO.getGender(), sdkFaceUserInfoGetVO.getFacePicUrl(), sdkFaceUserInfoGetVO.getFaceCreateTime(),
                                sdkFaceUserInfoGetVO.getIsFace(), sdkUserInfoGetRoomVOS);
                linkedHashMap.put(userId, sdkUserInfoGetAssembleVO);
            } else {
                SDKUserInfoGetAssembleVO sdkUserInfoGetAssembleVO = linkedHashMap.get(userId);
                List<SDKUserInfoGetRoomVO> sdkUserInfoGetRoomVOS = sdkUserInfoGetAssembleVO.getUserRoomInfoS();
                SDKUserInfoGetRoomVO sdkUserInfoGetRoomVO = new SDKUserInfoGetRoomVO();
                BeanUtils.copyProperties(sdkFaceUserInfoGetVO, sdkUserInfoGetRoomVO);
                sdkUserInfoGetRoomVOS.add(sdkUserInfoGetRoomVO);
                sdkUserInfoGetAssembleVO.setUserRoomInfoS(sdkUserInfoGetRoomVOS);
                linkedHashMap.put(userId, sdkUserInfoGetAssembleVO);
            }
        }
        for (String userId : userIdSet) {
            sdkUserInfoGetAssembleVOS.add(linkedHashMap.get(userId));
        }
        return sdkUserInfoGetAssembleVOS;
    }

    /**
     * <desc>
     * 组装设备信息返回
     * <desc/>
     *
     * @param sdkFaceDeviceInfoGetVOS 设备信息对象
     * @return List<SDKDeviceInfoGetAssembleVO> 组装过的设备信息
     * @author Qiang.S
     * @createDate 2019/11/06
     */
    private List<SDKDeviceInfoGetAssembleVO> assembleApiDeviceInfoGetVO(List<SDKFaceDeviceInfoGetVO> sdkFaceDeviceInfoGetVOS) {
        //返回结果
        List<SDKDeviceInfoGetAssembleVO> sdkDeviceInfoGetAssembleVOS = new ArrayList<>();
        //用于组装合并数据
        LinkedHashMap<String, SDKDeviceInfoGetAssembleVO> linkedHashMap = new LinkedHashMap<>();
        //记录设备
        LinkedHashSet<String> deviceUniqueSet = new LinkedHashSet<>();
        if (sdkFaceDeviceInfoGetVOS.isEmpty()) {
            return sdkDeviceInfoGetAssembleVOS;
        }
        //遍历
        for (SDKFaceDeviceInfoGetVO sdkFaceDeviceInfoGetVO : sdkFaceDeviceInfoGetVOS) {
            String deviceUnique = sdkFaceDeviceInfoGetVO.getDeviceUnique();
            deviceUniqueSet.add(deviceUnique);
            //相同设备合并地址信息
            if (linkedHashMap.get(deviceUnique) == null) {
                List<SDKDeviceInfoGetAddressVO> sdkDeviceInfoGetAddressVOS = new ArrayList<>();
                SDKDeviceInfoGetAddressVO sdkDeviceInfoGetAddressVO = new SDKDeviceInfoGetAddressVO();
                BeanUtils.copyProperties(sdkFaceDeviceInfoGetVO, sdkDeviceInfoGetAddressVO);
                sdkDeviceInfoGetAddressVOS.add(sdkDeviceInfoGetAddressVO);
                SDKDeviceInfoGetAssembleVO sdkDeviceInfoGetAssembleVO =
                        new SDKDeviceInfoGetAssembleVO(deviceUnique, sdkFaceDeviceInfoGetVO.getDeviceName(), sdkFaceDeviceInfoGetVO.getDeviceId(), sdkDeviceInfoGetAddressVOS);
                linkedHashMap.put(deviceUnique, sdkDeviceInfoGetAssembleVO);
            } else {
                SDKDeviceInfoGetAssembleVO sdkDeviceInfoGetAssembleVO = linkedHashMap.get(deviceUnique);
                List<SDKDeviceInfoGetAddressVO> sdkDeviceInfoGetAddressVOS = sdkDeviceInfoGetAssembleVO.getDeviceAddressInfoS();
                SDKDeviceInfoGetAddressVO sdkDeviceInfoGetAddressVO = new SDKDeviceInfoGetAddressVO();
                BeanUtils.copyProperties(sdkFaceDeviceInfoGetVO, sdkDeviceInfoGetAddressVO);
                sdkDeviceInfoGetAddressVOS.add(sdkDeviceInfoGetAddressVO);
                sdkDeviceInfoGetAssembleVO.setDeviceAddressInfoS(sdkDeviceInfoGetAddressVOS);
                linkedHashMap.put(deviceUnique, sdkDeviceInfoGetAssembleVO);
            }
        }
        for (String deviceUnique : deviceUniqueSet) {
            sdkDeviceInfoGetAssembleVOS.add(linkedHashMap.get(deviceUnique));
        }
        return sdkDeviceInfoGetAssembleVOS;
    }

    /**
     * <desc>
     * 人脸判断
     * <desc/>
     *
     * @return Object   标准格式化响应结果
     * @author Qiang.S
     * @createDate 2019/11/05
     */
    private SDKMessageVO checkFace(AppCreateBaiduFaceVO appCreateBaiduFaceVO) {
        String checkResult = iIotBaiduFaceServiceClient.faceVerify(appCreateBaiduFaceVO);
        if (checkResult != null && !"".equals(checkResult)) {
            if ("error".equals(checkResult)) {//调用接口异常
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_FACEVERFY_ERROR.getErrorCode(), appCreateBaiduFaceVO.getRequestId(), appCreateBaiduFaceVO.getResponseTimestamp(), "");
            }
            if ("busy".equals(checkResult)) {//调用接口忙
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_BAIDU_BUSY.getErrorCode(), appCreateBaiduFaceVO.getRequestId(), appCreateBaiduFaceVO.getResponseTimestamp(), "");
            }
            if ("others".equals(checkResult)) {//图片不合格,非真人图片
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_BAIDU_PICTURE_ERROR.getErrorCode(), appCreateBaiduFaceVO.getRequestId(), appCreateBaiduFaceVO.getResponseTimestamp(), "");
            }
            if ("result_num".equals(checkResult)) {//人脸数异常
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_FACE_RESULTNUM_NOT_1.getErrorCode(), appCreateBaiduFaceVO.getRequestId(), appCreateBaiduFaceVO.getResponseTimestamp(), "");
            }
            if ("size".equals(checkResult)) {//人脸太小
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_FACE_SIZE_TOO_SMALL.getErrorCode(), appCreateBaiduFaceVO.getRequestId(), appCreateBaiduFaceVO.getResponseTimestamp(), "");
            }
            //2020年8月5号 按照需求说明取消活体检测
           /* if ("faceliveness".equals(checkResult)) {//活体值异常
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_FACE_FACELIVENESS_TOO_LOW.getErrorCode(),appCreateBaiduFaceVO.getRequestId(),appCreateBaiduFaceVO.getResponseTimestamp(),"");
            }*/
            if ("left_eye".equals(checkResult) || "right_eye".equals(checkResult) || "nose".equals(checkResult)
                    || "mouth".equals(checkResult) || "left_cheek".equals(checkResult) || "right_cheek".equals(checkResult)
                    || "chin".equals(checkResult)) {//图片遮挡
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_FACE_OCCLUSION.getErrorCode(), appCreateBaiduFaceVO.getRequestId(), appCreateBaiduFaceVO.getResponseTimestamp(), "");
            }
            if ("blur".equals(checkResult)) {//模糊
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_FACE_BLUR_TOO_LOW.getErrorCode(), appCreateBaiduFaceVO.getRequestId(), appCreateBaiduFaceVO.getResponseTimestamp(), "");
            }
            if ("illumination_min".equals(checkResult)) {//光照过暗
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_FACE_ILLUMINATION_TOO_LOW.getErrorCode(), appCreateBaiduFaceVO.getRequestId(), appCreateBaiduFaceVO.getResponseTimestamp(), "");
            }
            if ("illumination_max".equals(checkResult)) {//光照过亮
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_FACE_ILLUMINATION_TOO_HIGH.getErrorCode(), appCreateBaiduFaceVO.getRequestId(), appCreateBaiduFaceVO.getResponseTimestamp(), "");
            }
            if ("pitch".equals(checkResult) || "roll".equals(checkResult) || "yaw".equals(checkResult)) {//角度
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_FACE_ANGLE_NOT_STRAIGHT.getErrorCode(), appCreateBaiduFaceVO.getRequestId(), appCreateBaiduFaceVO.getResponseTimestamp(), "");
            }
            if ("completeness".equals(checkResult)) {//人脸完整度
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_FACE_COMPLETENESS_IMPERFECT.getErrorCode(), appCreateBaiduFaceVO.getRequestId(), appCreateBaiduFaceVO.getResponseTimestamp(), "");
            }
        }
        //  2020年8月5号 按照需求说明取消人脸重复比对
      /*  //判断认证图片是否重复
        String repeatResult = iIotBaiduFaceServiceClient.identifyUser(appCreateBaiduFaceVO);
        if (repeatResult != null && !"".equals(repeatResult)) {
            if ("error".equals(repeatResult)) {//调用接口异常
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_IDENTIFY_ERROR.getErrorCode(),appCreateBaiduFaceVO.getRequestId(),appCreateBaiduFaceVO.getResponseTimestamp(),"");
            }
            if ("busy".equals(repeatResult)) {//调用接口忙
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_BAIDU_BUSY.getErrorCode(),appCreateBaiduFaceVO.getRequestId(),appCreateBaiduFaceVO.getResponseTimestamp(),"");
            }
            if ("face_repeat".equals(repeatResult)) {//人脸重复注册
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_CREATE_FACE_REPEAT.getErrorCode(),appCreateBaiduFaceVO.getRequestId(),appCreateBaiduFaceVO.getResponseTimestamp(),"");
            }
        }*/
        return null;
    }

    /**
     * <desc>
     * 保存人脸
     * <desc/>
     *
     * @return Object   标准格式化响应结果
     * @author Qiang.S
     * @createDate 2019/11/05
     */
    private SDKMessageVO saveUserFace(String userId, String uploadFilePath, CloudFaceApiDTO dto, AppCreateBaiduFaceVO appCreateBaiduFaceVO) throws Exception {
        //保存数据
        AppUserProjectPO appUserProjectPO = new AppUserProjectPO();
        appUserProjectPO.setUserId(userId);
        appUserProjectPO.setProjectId(dto.getProjectId());
        appUserProjectPO.setFacePicUrl(uploadFilePath);
        appUserProjectPO.setFaceCreateTime(new Date());
        appUserProjectPO.setUpdateTime(new Date());
        appUserProjectPO.setIsFace(2);//认证中
        int updateNumber = iPropertyHouseHoldInfoServiceClient.updatePreUserBaiduFaceInfo(appUserProjectPO);
        if (updateNumber == 0) {
            return new SDKMessageVO(BaseErrorCodeEnum.ERROR.getErrorCode(), dto.getRequestId(), dto.getResponseTimestamp(), "");
        }

        //添加人脸注册信息到队列
        appCreateBaiduFaceVO.setProjectId(dto.getProjectId());
        appCreateBaiduFaceVO.setUserPhone(dto.getPhoneNum());
        appCreateBaiduFaceVO.setUid(userId);
        appCreateBaiduFaceVO.setUserName(dto.getRealName());
        appCreateBaiduFaceVO.setUserInfo(dto.getRealName());//userInfo使用用户名
        appCreateBaiduFaceVO.setUploadFilePath(uploadFilePath);
        boolean resultCreateFace = iIotBaiduFaceServiceClient.createBaiduFace(appCreateBaiduFaceVO);
        if (!resultCreateFace) {
            return new SDKMessageVO(BaseErrorCodeEnum.ERROR.getErrorCode(), dto.getRequestId(), dto.getResponseTimestamp(), "");
        }
        return null;
    }

    /**
     * <desc>
     * 上传图片文件
     * <desc/>
     *
     * @param bytes     图片二进制
     * @param imageType 图片类型
     * @return
     * @author Qiang.S
     * @createDate 2018-05-18
     */
    private String uploadImageFile(byte[] bytes, String imageType, FileCatalogEnum fileCatalog) {
        byte[] newbytes = ImgageUtil.stringToImage(bytes, imageType);
        ByteArrayInputStream byteArrayInputStream = null;
        if (newbytes != null) {
            byteArrayInputStream = new ByteArrayInputStream(newbytes);
        } else {
            byteArrayInputStream = new ByteArrayInputStream(bytes);
        }
        UploadFileUtil.UploadFile uploadFileUtil = new UploadFileUtil().new UploadFile(
                FILE_FTP_HOST,
                FILE_FTP_USERNAME,
                FILE_FTP_PASSWORD,
                FILE_FTP_PORT,
                byteArrayInputStream,
                imageType,
                FILE_ACCESS_URL,
                fileCatalog.getType()
        );

        try {
            //LOG.info("正在上传图片");
            Map<String, Object> resultMap = UploadFileUtil.uploadFile(uploadFileUtil);
            //LOG.info("图片上传完毕");
            String returnCode = resultMap.get("returnCode").toString();
            if ("true".equals(returnCode)) {
                String fileUrl = resultMap.get("accessPath").toString();
                return fileUrl;
            } else {
                LOG.info(String.format("图片上传失败，returnCode: %s", returnCode));
                return null;
            }
        } catch (IOException e) {
            LOG.info("UploadFileUtil.uploadFile失败", e);
            return null;
        }
    }


    /**
     * <desc>
     * 判断添加住户业主房间地址时房间是否已存在业主
     * <desc/>
     *
     * @param appUserRoomDTOS App用户房间信息传输数据集
     * @return Map<String, String> :
     * Map<String, value> isExist业主是否存在，roomNum 业主存在时的房间号,userId 业主userId
     * @author zhangs
     * @createDate 2017/09/20
     */
    private Map<String, String> checkOwnerExist(List<AppUserRoomDTO> appUserRoomDTOS) {
        Map<String, String> resultMap = new HashMap<>();
        if (appUserRoomDTOS == null || (appUserRoomDTOS.isEmpty())) {
            resultMap.put("isExist", "false");
            return resultMap;
        }
        for (AppUserRoomDTO appUserRoomDTO : appUserRoomDTOS) {
            if (appUserRoomDTO.getHouserType() == AppUserRoomHouserTypeEnum.USERROOM_HOUSERTYPE_OWNER.getType()) {
                AppUserRoomOwnerIsExistDTO appUserRoomOwnerIsExistDTO = new AppUserRoomOwnerIsExistDTO();
                appUserRoomOwnerIsExistDTO.setRoomId(appUserRoomDTO.getRoomId());
                //获取roomId对应房间是否已存在业主
                List<AppUserRoomPO> appUserRoomPOS =
                        iPropertyHouseHoldInfoServiceClient.getExistHouserByRoom(appUserRoomOwnerIsExistDTO);
                if (appUserRoomPOS != null && appUserRoomPOS.size() > 0) {
                    resultMap.put("isExist", "true");
                    resultMap.put("roomNum", appUserRoomDTO.getRoomNum());
                    resultMap.put("userId", appUserRoomPOS.get(0).getUserId());
                    break;
                }
            }
        }
        return resultMap;
    }

    /**
     * <desc>
     * 保存访客人脸(私有)
     * </desc>
     *
     * @param dto 接收数据dto类
     * @return
     * @author Qiang.S
     * @createDate 2019/02/26
     */
    private SDKMessageVO setVisitPassFacePrivate(MiniSetVisitPassFaceDTO dto) throws Exception {
        if (StringUtils.isBlank(dto.getImageStr())) {
            return new SDKMessageVO(AppErrorCodeEnum.IMAGE_DATA_INVALID.getErrorCode(), dto.getRequestId(), dto.getResponseTimestamp(), "");
        }
        Map<String, Object> map = new HashMap<>();
        //判断项目是否开启人脸识别,并查询是否有百度库key
        OperateFaceApplyInfoVO operateFaceApplyInfoVO = iOperateFaceApplyServiceClient.getFaceByProjectId(dto.getProjectId());
        if (operateFaceApplyInfoVO == null) {
            return new SDKMessageVO(AppErrorCodeEnum.PROJECT_FACE_APPID_INEXISTENCE.getErrorCode(), dto.getRequestId(), dto.getResponseTimestamp(), "");
        }
        //访客人脸注册时,判断人脸库中是否有此人数据
        AppCreateBaiduFaceVO appCreateBaiduFaceVO = new AppCreateBaiduFaceVO();
        appCreateBaiduFaceVO.setAPP_ID(operateFaceApplyInfoVO.getAppId());
        appCreateBaiduFaceVO.setAPI_KEY(operateFaceApplyInfoVO.getApiKey());
        appCreateBaiduFaceVO.setSECRET_KEY(operateFaceApplyInfoVO.getSecretKey());
        appCreateBaiduFaceVO.setFaceScore(operateFaceApplyInfoVO.getFaceScore() == 0F ? 80F : operateFaceApplyInfoVO.getFaceScore());
        //判断图片分辨率
        BufferedImage bi = ImageIO.read(new ByteArrayInputStream(new BASE64Decoder().decodeBuffer(dto.getImageStr())));
        int width = bi.getWidth();
        int height = bi.getHeight();
        if (width < 640 || height < 480 || width > 2560 || height > 2560) {
            return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_FACE_RESOLUTION_RATIO_ERROR.getErrorCode(), appCreateBaiduFaceVO.getRequestId(), appCreateBaiduFaceVO.getResponseTimestamp(), "");
        }
        String uploadFilePath = uploadImageFile(new BASE64Decoder().decodeBuffer(dto.getImageStr()), "jpg", FileCatalogEnum.BAIDU_FACE_CREATE_FILE);
        appCreateBaiduFaceVO.setImageUrl(uploadFilePath);
        if (StringUtils.isBlank(uploadFilePath)) {
            return new SDKMessageVO(AppErrorCodeEnum.IMAGE_UPLOAD_FAILED.getErrorCode(), dto.getRequestId(), dto.getResponseTimestamp(), "");
        }
        String checkResult = iIotBaiduFaceServiceClient.faceVerify(appCreateBaiduFaceVO);
        if (checkResult != null && !"".equals(checkResult)) {
            if ("error".equals(checkResult)) {//调用接口异常
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_FACEVERFY_ERROR.getErrorCode(), dto.getRequestId(), dto.getResponseTimestamp(), "");
            }
            if ("busy".equals(checkResult)) {//调用接口忙
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_BAIDU_BUSY.getErrorCode(), dto.getRequestId(), dto.getResponseTimestamp(), "");
            }
            if ("others".equals(checkResult)) {//图片不合格,非真人图片
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_BAIDU_PICTURE_ERROR.getErrorCode(), dto.getRequestId(), dto.getResponseTimestamp(), "");
            }
            if ("result_num".equals(checkResult)) {//人脸数异常
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_FACE_RESULTNUM_NOT_1.getErrorCode(), dto.getRequestId(), dto.getResponseTimestamp(), "");
            }
            if ("size".equals(checkResult)) {//人脸太小
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_FACE_SIZE_TOO_SMALL.getErrorCode(), appCreateBaiduFaceVO.getRequestId(), appCreateBaiduFaceVO.getResponseTimestamp(), "");
            }
            //2020年8月5号 按照需求说明取消活体检测
            /*if ("faceliveness".equals(checkResult)) {//活体值异常
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_FACE_FACELIVENESS_TOO_LOW.getErrorCode(),dto.getRequestId(),dto.getResponseTimestamp(),"");
            }*/
            if ("left_eye".equals(checkResult) || "right_eye".equals(checkResult) || "nose".equals(checkResult)
                    || "mouth".equals(checkResult) || "left_cheek".equals(checkResult) || "right_cheek".equals(checkResult)
                    || "chin".equals(checkResult)) {//图片遮挡
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_FACE_OCCLUSION.getErrorCode(), dto.getRequestId(), dto.getResponseTimestamp(), "");
            }
            if ("blur".equals(checkResult)) {//模糊
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_FACE_BLUR_TOO_LOW.getErrorCode(), dto.getRequestId(), dto.getResponseTimestamp(), "");
            }
            if ("illumination_min".equals(checkResult)) {//光照过暗
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_FACE_ILLUMINATION_TOO_LOW.getErrorCode(), appCreateBaiduFaceVO.getRequestId(), appCreateBaiduFaceVO.getResponseTimestamp(), "");
            }
            if ("illumination_max".equals(checkResult)) {//光照过亮
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_FACE_ILLUMINATION_TOO_HIGH.getErrorCode(), appCreateBaiduFaceVO.getRequestId(), appCreateBaiduFaceVO.getResponseTimestamp(), "");
            }
            if ("pitch".equals(checkResult) || "roll".equals(checkResult) || "yaw".equals(checkResult)) {//角度
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_FACE_ANGLE_NOT_STRAIGHT.getErrorCode(), dto.getRequestId(), dto.getResponseTimestamp(), "");
            }
            if ("completeness".equals(checkResult)) {//人脸完整度
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_FACE_COMPLETENESS_IMPERFECT.getErrorCode(), dto.getRequestId(), dto.getResponseTimestamp(), "");
            }
        }
        String repeatResult = iIotBaiduFaceServiceClient.identifyUser(appCreateBaiduFaceVO);//拿到现有的id
        if (repeatResult != null && !"".equals(repeatResult)) {
            if ("error".equals(repeatResult)) {//调用接口异常
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_IDENTIFY_ERROR.getErrorCode(), dto.getRequestId(), dto.getResponseTimestamp(), "");
            }
            if ("busy".equals(repeatResult)) {//调用接口忙
                return new SDKMessageVO(PropertyErrorCodeEnum.APPUSER_BAIDU_BUSY.getErrorCode(), dto.getRequestId(), dto.getResponseTimestamp(), "");
            }
        }
        String vFaceId;
        //判断认证图片是否重复
        if (repeatResult == null) {//人脸库中无此人脸ID使用V_ + pass_id
            appCreateBaiduFaceVO.setUid("V_" + dto.getPassId());
            //创建百度人脸信息
            boolean result = iIotBaiduFaceServiceClient.doCreateBaiduFaceForVisitor(appCreateBaiduFaceVO);
            if (!result) {
                map.put("result", "2");
                return new SDKMessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), dto.getRequestId(), dto.getResponseTimestamp(),
                        Md5EncryptUtil.getSDKV2Md5(map, dto.getRequestId(), dto.getResponseTimestamp(), dto.getAppSecret()), map);
            }
            vFaceId = appCreateBaiduFaceVO.getUid();
        } else {//人脸库中有此人脸
            //有此人脸时证明这个人在此项目中注册过人脸业主使用的是这个人的user_id,访客使用的是V_ + pass_id   不进行重复注册
            if (repeatResult.substring(0, 2).equals("V_")) {//访客人脸则进行覆盖
                appCreateBaiduFaceVO.setUid(repeatResult);
                //创建百度人脸信息
                boolean result = iIotBaiduFaceServiceClient.doCreateBaiduFaceForVisitor(appCreateBaiduFaceVO);
                if (!result) {
                    map.put("result", "2");
                    return new SDKMessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), dto.getRequestId(), dto.getResponseTimestamp(),
                            Md5EncryptUtil.getSDKV2Md5(map, dto.getRequestId(), dto.getResponseTimestamp(), dto.getAppSecret()), map);
                }
            }
            vFaceId = repeatResult;
        }
        iAppVisitorPassCodeRecordServiceClient.setVisitPassFace(dto.getPassId(), uploadFilePath, vFaceId, dto.getProjectId(), dto.getIdcardKey() == null ? "" : dto.getIdcardKey(), 0);

        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        map.put("authDate", formatter.format(currentTime));
        map.put("result", "1");
        map.put("uploadFilePath", uploadFilePath);
        //查询当前项目信息
        ProjectPO projectPO = iOperateProjectServiceClient.getOneProject(dto.getProjectId());
        // 平板优先离线，则插入同步数据
        if (projectPO.getOnOffLinePadFace() != null) {
            PadFaceSyncDataDTO padFaceSyncDataDTO = new PadFaceSyncDataDTO();
            padFaceSyncDataDTO.setOperateType("3");
            padFaceSyncDataDTO.setProjectId(dto.getProjectId());
            padFaceSyncDataDTO.setPassId(dto.getPassId());
            padFaceSyncDataDTO.setStatus("1");
            padFaceSyncDataDTO.setSourceSystem(4);
            iPadFaceSyncDataServiceClient.userOrFloorSync(padFaceSyncDataDTO);
            iPadFaceSyncDataServiceClient.userOrFloorSyncSmartCard(padFaceSyncDataDTO);
        }
        return new SDKMessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), dto.getRequestId(), dto.getResponseTimestamp(),
                Md5EncryptUtil.getSDKV2Md5(map, dto.getRequestId(), dto.getResponseTimestamp(), dto.getAppSecret()), map);
    }
}
